import React, { useState, useEffect, forwardRef } from 'react';
import { Table, Form, Button, Divider } from 'antd';
import styles from './index.less';

/*
  使用demo
  初始值要给上id。
  拿到数据后要去掉id和type属性。

  <Form.Item>
    {getFieldDecorator('text', {
      initialValue: [
        {
          id: 0,
          field1:0,
          field2:0,
        },
        {
          id: 1,
          field1:1,
          field2:1
        },
      ],
    })(
      <Editable
        columns={[
          {
            title: '字段1',
            key: 'field1',
            options: {},
            widget: (
              <Select
                placeholder="请选择
                style={{
                  width: 300,
                }}
              >
                {['1', '2'].map(item => (
                  <Select.Option value={item} key={item}>
                    {item}
                  </Select.Option>
                ))}
              </Select>
            ),
          },
          {
            title: '字段2',
            key: 'filed2',
            options: {},
            widget: <Input placeholder="请输入" />,
          },
        ]}
      ></Editable>,
    )}
  </Form.Item>
*/

let pKey = 2; // data.length
const EditableContext = React.createContext();

const EditableRow = props => {
  const { form, ...rProps } = props;
  return (
    <EditableContext.Provider value={form}>
      <tr {...rProps}></tr>
    </EditableContext.Provider>
  );
};
const EditableFormRow = Form.create()(EditableRow);

const EditableCell = ({ renderDom, record, ...rProps }) => (
  <td {...rProps}>
    <EditableContext.Consumer>{form => renderDom(form, record)}</EditableContext.Consumer>
  </td>
);

const EditableForm = ({ columns: cols, onChange, value }, ref) => {
  const [data, setData] = useState([]);
  const [isRowOpen, setIsRowOpen] = useState(false);

  useEffect(() => {
    let tData = Array.isArray(value) ? [...value] : [];
    tData = tData.map(item => ({ ...item, type: 'view' }));
    updateDataSource(tData);
  }, [undefined]);

  const columns = cols.map(({ title, key, widget, options }) => ({
    title,
    key,
    renderDom: (form, record) => {
      if (record.type !== 'view') {
        return (
          <Form.Item>
            {form.getFieldDecorator(key, {
              initialValue: record[key],
              ...options,
            })(widget)}
          </Form.Item>
        );
      }
      return record[key];
    },
  }));
  columns.push({
    title: '操作',
    renderDom: (form, record) => (
      <span>
        {record.type === 'new' && (
          <span>
            <a onClick={() => addSubmit(form, record)}>完成</a>
            <Divider type="vertical" />
            <a onClick={() => removeAdd(record)}>取消</a>
          </span>
        )}
        {record.type === 'edit' && (
          <span>
            <a onClick={() => editSubmit(form, record)}>完成</a>
            <Divider type="vertical" />
            <a onClick={() => dropUpdate(record)}>取消</a>
            <Divider type="vertical" />
            <a onClick={() => deleteRow(record)}>删除</a>
          </span>
        )}
        {record.type === 'view' && (
          <span>
            <a onClick={() => edit(record)}>编辑</a>
            <Divider type="vertical" />
            <a onClick={() => deleteRow(record)}>删除</a>
          </span>
        )}
      </span>
    ),
  });

  // new状态时提交
  function addSubmit(form, record) {
    const newData = [...data];
    form.validateFields((err, val) => {
      if (err) {
        return;
      }
      const updateData = { ...record, ...val, type: 'view' };
      newData.pop();
      newData.push(updateData);
      updateDataSource(newData);
    });
  }

  // new状态时删除
  function removeAdd() {
    const newData = [...data];
    newData.pop();
    updateDataSource(newData);
  }

  // edit状态时提交
  function editSubmit(form, record) {
    const newData = [...data];
    form.validateFields((err, val) => {
      if (err) {
        return;
      }
      const updateData = { ...record, ...val };
      newData.forEach((item, index) => {
        if (item.id === updateData.id) {
          newData[index] = { ...updateData, type: 'view' };
        }
      });
      updateDataSource(newData);
    });
  }

  // edit状态时取消
  function dropUpdate(record) {
    const newData = [...data];
    const editRow = newData.find(item => item.id === record.id);
    editRow.type = 'view';
    updateDataSource(newData);
  }

  // view状态下编辑
  function edit(record) {
    let newData = [...data];
    newData = newData.map(item => {
      if (item.id === record.id) {
        return {
          ...item,
          type: 'edit',
        };
      }
      if (item.type !== 'new') {
        return {
          ...item,
          type: 'view',
        };
      }
      return {
        ...item,
      };
    });
    updateDataSource(newData, true);
  }

  // edit/view状态时删除
  function deleteRow(record) {
    const newData = [...data];
    const index = newData.findIndex(item => item.id === record.id);
    newData.splice(index, 1);
    updateDataSource(newData);
  }

  // 添加行
  function addRow() {
    const tObj = {};
    columns.forEach(({ key }) => {
      tObj[key] = undefined;
    });
    pKey += 1;
    tObj.id = pKey;
    tObj.type = 'new';
    const newData = [...data, { ...tObj }];
    updateDataSource(newData);
  }

  // 更新DataSource
  function updateDataSource(newData, isAddDisabled) {
    setData(newData);
    setIsRowOpen(
      isAddDisabled || newData.some(item => item.type === 'new' || item.type === 'edit'),
    );
    onChange(newData);
  }

  const tableColumns = columns.map(col => ({
    ...col,
    onCell: record => ({
      ...col,
      record,
    }),
  }));

  return (
    <div className={styles.editable} ref={ref}>
      <Table
        size="small"
        rowKey={(_, index) => index}
        components={{
          body: {
            row: EditableFormRow,
            cell: EditableCell,
          },
        }}
        columns={tableColumns}
        dataSource={data}
        pagination={false}
      ></Table>
      <Button
        type="dashed"
        disabled={isRowOpen}
        onClick={addRow}
        icon="plus"
        style={{
          // position: 'absolute',
          // bottom: '-36px',
          width: '100%',
        }}
      >
        添加
      </Button>
    </div>
  );
};

export default forwardRef(EditableForm);
